package czy.demo.config.shiro;

import czy.demo.entity.system.Permission;
import czy.demo.entity.system.Role;
import czy.demo.entity.system.User;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.biz.realm.AbstractAuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.stream.Collectors;


/* 自定义的Realm类，自动配置会把Realm的实例设置到安全管理器
 * 继承了AbstractAuthorizingRealm类，需要注入
 * List<AuthorizingRealmListener> realmsListeners：realm监听器，用于监听认证成功、失败事件
 * ShiroPrincipalRepository repository：仓库，用于根据用户名密码获取认证信息
 */
@Component
public class DefaultShiroRealm extends AbstractAuthorizingRealm implements InitializingBean {

    private static final Logger logger = LoggerFactory.getLogger(DefaultShiroRealm.class);

    @Autowired
    private DefaultShiroPrincipalRepository principalRepository;

    /* 获取授权信息方法 */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        User user = (User)principals.getPrimaryPrincipal();
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.setRoles(user.getRoles().stream().filter(Role::getEnabled).map(Role::getName).collect(Collectors.toSet()));
        info.setObjectPermissions(user.getRoles().stream().filter(Role::getEnabled).map(Role::getPermissions).flatMap(List::stream).distinct().filter(Permission::getEnabled).collect(Collectors.toSet()));
        return info;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        /* 设置principalRepository到realm */
        this.setRepository(principalRepository);
    }
}
